//
// Created on 2024/11/28.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".

#include "headers/PluginManager.h"
#include "Log.h"

PluginManager PluginManager::m_pluginManager;

PluginManager::~PluginManager() { nativeXComponentMap_.clear(); }

void PluginManager::Export(napi_env env, napi_value exports) {
    if ((nullptr == env) || (nullptr == exports)) {
        LOG_I("HomeNavigation Export: env or exports is null");
        return;
    }
    napi_value exportInstance = nullptr;
    if (napi_ok != napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance)) {
        LOG_I("HomeNavigation Export: napi_get_named_property fail");
        return;
    }

    OH_NativeXComponent *nativeXComponent = nullptr;
    if (napi_ok != napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent))) {
        LOG_I("HomeNavigation Export: napi_unwrap fail");
        return;
    }

    char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
    uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
    if (OH_NATIVEXCOMPONENT_RESULT_SUCCESS != OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize)) {
        LOG_I("HomeNavigation Export: OH_NativeXComponent_GetXComponentId fail");
        return;
    }
    std::string id(idStr);
    LOG_I("HomeNavigation Export: id :%{public}s", idStr);
    LOG_I("HomeNavigation Export: nativeXComponent is null :%{public}d", nativeXComponent == nullptr);
    auto context = PluginManager::GetInstance();
    if ((nullptr != context) && (nullptr != nativeXComponent)) {
        context->setNativeXComponent(id, nativeXComponent);
    }
}

void PluginManager::setNativeXComponent(std::string id, OH_NativeXComponent *nativeXComponent) {
    if (nativeXComponent == nullptr) {
        return;
    }
    if (nativeXComponentMap_.find(id) != nativeXComponentMap_.end()) {
        removeComponent(id);
    }
    PluginWindowRender *newRender = new PluginWindowRender(id, nativeXComponent);
    nativeXComponentMap_[id] = newRender;
    OH_NativeXComponent_RegisterCallback(nativeXComponent, &newRender->m_callback);
}

PluginWindowRender *PluginManager::getRender(std::string id) {
    if (nativeXComponentMap_.find(id) == nativeXComponentMap_.end()) {
        return nullptr;
    } else {
        return nativeXComponentMap_[id];
    }
}

void PluginManager::removeComponent(std::string id) {
    PluginWindowRender *render = getRender(id);
    if (render) {
        delete render;
    }
    nativeXComponentMap_.erase(id);
}
